package dao

import (
	"context"
	"errors"
	"gitee.com/goddesszz/gocommon/myutil"
	"github.com/qiniu/qmgo"
	"github.com/sirupsen/logrus"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"monoblog/config"
	"monoblog/domain/model"
	"sync"
)

var (
	collectRelationRepo *CollectRelationRepository // 单例实例存储变量
	once4               sync.Once                  // 确保初始化只执行一次的同步工具
)

// 初始化 QMGO 集合（单例模式）
func NewCollectRelationRepository() *CollectRelationRepository {
	once4.Do(func() { // 并发安全的初始化逻辑，只会执行一次
		collectRelationRepo = &CollectRelationRepository{
			collection: config.GetDataBase().Collection(model.CollectRelationCollectionName), //指定集合名称
			ctx:        context.Background(),
		}
	})
	return collectRelationRepo // 返回唯一实例
}

type CollectRelationRepository struct {
	collection *qmgo.Collection // QMGO 集合对象（替代原生 mongo.Collection）
	ctx        context.Context  // 上下文（用于数据库操作超时控制）
}

func (impl CollectRelationRepository) Add(collectRelation *model.CollectRelation) error {
	// 取自增ID
	id, _ := NewAutoIDSequenceDao().NextID(model.CollectRelationCollectionName)
	collectRelation.ID = id

	_, err := impl.collection.InsertOne(impl.ctx, collectRelation)
	return err
}

// Delete 删除
func (impl CollectRelationRepository) Delete(collectRelation *model.CollectRelation) (bool, error) {
	// 构建查询条件
	filter := bson.M{
		"userId":      collectRelation.UserId,
		"targetId":    collectRelation.TargetId,
		"collectType": collectRelation.CollectType,
	}
	if collectRelation.SubTargetId != "" {
		filter["subTargetId"] = collectRelation.SubTargetId
	}

	err := impl.collection.Remove(impl.ctx, filter) // 执行删除操作
	if errors.Is(err, mongo.ErrNoDocuments) {
		logrus.Warnf("record not found. dont delete. filter: %v", filter)
		return false, nil
	}

	return err == nil, err
}

// Exists 查询是否存在
func (impl CollectRelationRepository) Exists(collectRelation *model.CollectRelation) (bool, error) {
	// 构建查询条件
	filter := bson.M{
		"userId":      collectRelation.UserId,
		"targetId":    collectRelation.TargetId,
		"collectType": collectRelation.CollectType,
	}
	if collectRelation.SubTargetId != "" {
		filter["subTargetId"] = collectRelation.SubTargetId
	}

	n, err := impl.collection.Find(impl.ctx, filter).Count()
	return n > 0, err
}

func (impl CollectRelationRepository) FindListByQuery(query *model.CollectQuery) ([]*model.CollectRelation, error) {
	var collects = make([]*model.CollectRelation, 0)
	if query == nil {
		return nil, errors.New("query is nil")
	}

	// 构建查询条件
	filter := bson.M{}
	if query.UserId != "" {
		filter["userId"] = query.UserId
	}
	if query.TargetId != "" {
		filter["targetId"] = query.TargetId
	}
	if len(query.CollectTypes) > 0 {
		filter["collectType"] = bson.M{"$in": query.CollectTypes}
	}

	err := impl.collection.Find(impl.ctx, filter).All(&collects)
	if err != nil {
		logrus.Errorf("find collect failed. query= %s, err: %v", myutil.JsonToString(query), err)
		return nil, err
	}
	return collects, nil
}
